home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / editors / mutt / me2s_pl7.zoo / mu_edit2 / util / wildmat.c < prev   
Encoding:
C/C++ Source or Header  |  1993-07-05  |  5.7 KB  |  220 lines

  1. static char rcsid[] = "$Id: wildmat.c,v 1.1 1992/09/06 19:31:32 mike Exp $";
  2.  
  3. /* $Log: wildmat.c,v $
  4.  * Revision 1.1  1992/09/06  19:31:32  mike
  5.  * Initial revision
  6.  *
  7.  */
  8.  
  9. /*
  10. **  Do shell-style pattern matching for ?, \, [], and * characters.
  11. **  Might not be robust in face of malformed patterns; e.g., "foo[a-"
  12. **  could cause a segmentation violation.  It is 8bit clean.
  13. **
  14. **  Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
  15. **  Rich $alz is now <rsalz@bbn.com>.
  16. **  Special thanks to Lars Mathiesen <thorinn@diku.dk> for the ABORT code.
  17. **  This can greatly speed up failing wildcard patterns.  For example:
  18. **    pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-*
  19. **    text 1:     -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1
  20. **    text 2:     -adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1
  21. **  Text 1 matches with 51 calls, while text 2 fails with 54 calls.  Without
  22. **  the ABORT, then it takes 22310 calls to fail.  Ugh.
  23. **
  24. **  C Durland added:
  25. **    MS-DOS uses \ for path, so do nothing for \ in that case.
  26. **    Put man page at the end of this file.
  27. */
  28.  
  29. #include "os.h"        /* only used for MSDOZ, ATARI --CD */
  30.  
  31. #define TRUE        1
  32. #define FALSE        0
  33. #define ABORT        -1
  34.  
  35. #define NEGATE_CLASS    '^'
  36.  
  37. /* Forward declaration. */
  38. static int    DoMatch();
  39.  
  40. /*
  41. **  See if the text matches the p, which has an implied leading asterisk.
  42. */
  43. static int
  44. Star(text, p)
  45.     register char    *text;
  46.     register char    *p;
  47. {
  48.     register int    ret;
  49.  
  50.     do
  51.     ret = DoMatch(text++, p);
  52.     while (ret == FALSE);
  53.     return ret;
  54. }
  55.  
  56.  
  57. /*
  58. **  Match text and p, return TRUE, FALSE, or ABORT.
  59. */
  60. static int
  61. DoMatch(text, p)
  62.     register char    *text;
  63.     register char    *p;
  64. {
  65.     register int      last;
  66.     register int      matched;
  67.     register int      reverse;
  68.  
  69.     for ( ; *p; text++, p++) {
  70.     if (*text == '\0' && *p != '*')
  71.         return ABORT;
  72.     switch (*p) {
  73. #if !(MSDOZ || ATARI)        /* blame those bozos at Microsoft */
  74.     case '\\':
  75.         /* Literal match with following character. */
  76.         p++;
  77.         /* FALLTHROUGH */
  78. #endif
  79.     default:
  80.         if (*text != *p)
  81.         return FALSE;
  82.         continue;
  83.     case '?':
  84.         /* Match anything. */
  85.         continue;
  86.     case '*':
  87.         /* Trailing star matches everything. */
  88.         return *++p ? Star(text, p) : TRUE;
  89.     case '[':
  90.         if (reverse = p[1] == NEGATE_CLASS)
  91.         /* Inverted character class. */
  92.         p++;
  93.         for (last = 0400, matched = FALSE; *++p && *p != ']'; last = *p)
  94.         /* This next line requires a good C compiler. */
  95.         if (*p == '-' ? *text <= *++p && *text >= last : *text == *p)
  96.             matched = TRUE;
  97.         if (matched == reverse)
  98.         return FALSE;
  99.         continue;
  100.     }
  101.     }
  102.  
  103.     return *text == '\0';
  104. }
  105.  
  106.  
  107. /*
  108. **  User-level routine.  Returns TRUE or FALSE.
  109. */
  110. int
  111. wildmat(text, p)
  112.     char    *text;
  113.     char    *p;
  114. {
  115.     return DoMatch(text, p) == TRUE;
  116. }
  117.  
  118.  
  119.  
  120. #ifdef    TEST
  121. #include <stdio.h>
  122.  
  123. /* Yes, we use gets not fgets.  Sue me. */
  124. extern char    *gets();
  125.  
  126.  
  127. main()
  128. {
  129.     char     p[80];
  130.     char     text[80];
  131.  
  132.     printf("Wildmat tester.  Enter pattern, then strings to test.\n");
  133.     printf("A blank line gets prompts for a new pattern; a blank pattern\n");
  134.     printf("exits the program.\n\n");
  135.  
  136.     for ( ; ; ) {
  137.     printf("Enter pattern:  ");
  138.     (void)fflush(stdout);
  139.     if (gets(pattern) == NULL || pattern[0] == '\n')
  140.         break;
  141.     for ( ; ; ) {
  142.         printf("Enter text:  ");
  143.         (void)fflush(stdout);
  144.         if (gets(text) == NULL)
  145.         exit(0);
  146.         if (text[0] == '\0')
  147.         /* Blank line; go back and get a new pattern. */
  148.         break;
  149.         printf("      %s\n", wildmat(text, pattern) ? "YES" : "NO");
  150.     }
  151.     }
  152.  
  153.     exit(0);
  154.     /* NOTREACHED */
  155. }
  156. #endif    /* TEST */
  157.  
  158.  
  159.  
  160. #if 0        /* the man page */
  161.  
  162.  WILDMAT(3)                                                       WILDMAT(3)
  163.  
  164.  
  165.  NAME
  166.       wildmat - perform shell-style wildcard matching
  167.  
  168.  SYNOPSIS
  169.       int
  170.       wildmat(text, pattern)
  171.           char       *text;
  172.           char       *pattern;
  173.  
  174.  DESCRIPTION
  175.       Wildmat compares the text against the pattern and returns non-zero if
  176.       the pattern matches the text.  The pattern is interpreted similar to
  177.       shell filename wildcards, and not as a full regular expression such as
  178.       those handled by the grep(1) family of programs or the regex(3) or
  179.       regexp(3) set of routines.
  180.  
  181.       The pattern is interpreted according to the following rules:
  182.  
  183.       \x   Turns off the special meaning of x and matches it directly; this
  184.            is used mostly before a question mark or asterisk, and is not
  185.            valid inside square brackets.
  186.  
  187.       ?    Matches any single character.
  188.  
  189.       *    Matches any sequence of zero or more characters.
  190.  
  191.       [x...y]
  192.            Matches any single character specified by the set x...y, where
  193.            any character other than minus sign or close bracket may appear
  194.            in the set.  A minus sign may be used to indicate a range of
  195.            characters.  That is, [0-5abc] is a shorthand for [012345abc].
  196.            More than one range may appear inside a character set; [0-9a-zA-
  197.            Z._] matches almost all of the legal characters for a host name.
  198.  
  199.       [^x...y]
  200.            This matches any character not in the set x...y, which is
  201.            interpreted as described above.
  202.  
  203.  BUGS
  204.       There is no way to specify a minus sign in a character range.
  205.  
  206.  HISTORY
  207.       Written by Rich $alz <rsalz@bbn.com> in 1986, and posted to Usenet
  208.       several times since then, most notably in comp.sources.misc in March,
  209.       1991.
  210.       Lars Mathiesen <thorinn@diku.dk> enhanced the multi-asterisk failure
  211.       mode in early 1991.
  212.  
  213.  SEE ALSO
  214.       grep(1), regex(3), regexp(3).
  215.  
  216.  
  217.                                     - 1 -       Formatted:  January 17, 1992
  218.  
  219. #endif
  220.